package com.seecen.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.seecen.mapper.CheckinMapper;
import com.seecen.pojo.entity.Checkin;
import com.seecen.service.CheckinService;
import com.seecen.utils.JwtHelper;
import com.seecen.utils.Result;
import com.seecen.utils.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * @program: SharkBookkeeping-end
 * @description:
 * @author: XXW
 * @create: 2025-10-17 21:30
 * @version: 1.0
 **/
@Service
@Slf4j
public class CheckinServiceImpl extends ServiceImpl<CheckinMapper, Checkin>
        implements CheckinService {

    @Autowired
    private CheckinMapper checkinMapper;

    @Autowired
    private JwtHelper jwtHelper;

    @Override
    public Result checkin(String token) {
        // 验证token
        boolean isExpiration = jwtHelper.isExpiration(token);
        if(isExpiration) {
            return Result.build(null, ResultCode.NOTLOGIN);
        }

        Long userId = jwtHelper.getUserId(token);
        LocalDate today = LocalDate.now();

        // 检查今天是否已打卡
        LambdaQueryWrapper<Checkin> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Checkin::getUserId, userId)
                .eq(Checkin::getCheckinDate, Date.from(today.atStartOfDay(ZoneId.systemDefault()).toInstant()))
                .eq(Checkin::getIsDeleted, 0);

        Checkin existCheckin = checkinMapper.selectOne(wrapper);

        if(existCheckin != null) {
            // 今天已经打卡
            HashMap<String, Object> data = new HashMap<>();
            data.put("message", "今天已经打卡过了");
            data.put("alreadyChecked", true);
            data.put("continuousDays", getContinuousCheckinDays(userId));
            return Result.ok(data);
        }

        // 创建打卡记录
        Checkin checkin = new Checkin();
        checkin.setUserId(userId);
        checkin.setCheckinDate(Date.from(today.atStartOfDay(ZoneId.systemDefault()).toInstant()));
        checkin.setCreator(userId);
        checkin.setLastUpdator(userId);

        int insertResult = checkinMapper.insert(checkin);

        if(insertResult > 0) {
            HashMap<String, Object> data = new HashMap<>();
            data.put("message", "打卡成功");
            data.put("alreadyChecked", false);
            data.put("continuousDays", getContinuousCheckinDays(userId));
            log.info("用户 {} 打卡成功", userId);
            return Result.ok(data);
        } else {
            return Result.build(null, ResultCode.PASSWORD_ERROR); // 使用通用错误码
        }
    }

    @Override
    public int getContinuousCheckinDays(Long userId) {
        // 获取用户所有打卡记录，按日期降序排列
        LambdaQueryWrapper<Checkin> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Checkin::getUserId, userId)
                .eq(Checkin::getIsDeleted, 0)
                .orderByDesc(Checkin::getCheckinDate);

        List<Checkin> checkinList = checkinMapper.selectList(wrapper);

        if(checkinList == null || checkinList.isEmpty()) {
            return 0;
        }

        // 计算连续打卡天数
        LocalDate today = LocalDate.now();
        
        // 获取最近一次打卡的日期
        LocalDate firstCheckinDate = checkinList.get(0).getCheckinDate().toInstant()
                .atZone(ZoneId.systemDefault()).toLocalDate();
        
        // 如果最近一次打卡不是今天也不是昨天，说明打卡已中断
        if(firstCheckinDate.isBefore(today.minusDays(1))) {
            return 0;
        }
        
        // 从最近一次打卡的日期开始计算
        LocalDate checkDate = firstCheckinDate;
        int continuousDays = 0;

        for(Checkin checkin : checkinList) {
            LocalDate checkinDate = checkin.getCheckinDate().toInstant()
                    .atZone(ZoneId.systemDefault()).toLocalDate();

            if(checkinDate.equals(checkDate)) {
                continuousDays++;
                checkDate = checkDate.minusDays(1);
            } else if(checkinDate.equals(checkDate.plusDays(1))) {
                // 已经在前面计数过了，跳过
                continue;
            } else {
                // 打卡不连续，退出循环
                break;
            }
        }

        return continuousDays;
    }

    @Override
    public boolean hasCheckedInToday(Long userId) {
        LocalDate today = LocalDate.now();

        // 检查今天是否已打卡
        LambdaQueryWrapper<Checkin> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Checkin::getUserId, userId)
                .eq(Checkin::getCheckinDate, Date.from(today.atStartOfDay(ZoneId.systemDefault()).toInstant()))
                .eq(Checkin::getIsDeleted, 0);

        Checkin existCheckin = checkinMapper.selectOne(wrapper);

        return existCheckin != null;
    }
}